package com.example.service;

import com.google.code.kaptcha.Producer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@Service
public class CaptchaService {
    private static final Logger log = LoggerFactory.getLogger(CaptchaService.class);
    
    @Autowired
    private Producer captchaProducer;
    
    // 存储验证码的Map，key是captchaId，value是验证码文本
    private final Map<String, String> captchaStore = new ConcurrentHashMap<>();
    private final Random random = new Random();
    
    // 验证码类型
    public enum CaptchaType {
        IMAGE,      // 图片验证码
        MATH        // 数学计算验证码
    }
    
    public CaptchaService() {
        // 创建定时任务，清理过期的验证码
        Executors.newSingleThreadScheduledExecutor()
                .scheduleAtFixedRate(this::cleanExpiredCaptcha, 5, 5, TimeUnit.MINUTES);
    }
    
    /**
     * 生成图片验证码（默认类型）
     */
    public Map<String, String> generateCaptcha() {
        return generateCaptcha(CaptchaType.IMAGE);
    }
    
    /**
     * 根据指定类型生成验证码
     */
    public Map<String, String> generateCaptcha(CaptchaType type) {
        try {
            String captchaId = UUID.randomUUID().toString();
            Map<String, String> result = new HashMap<>();
            result.put("captchaId", captchaId);
            
            if (type == CaptchaType.MATH) {
                generateMathCaptcha(captchaId, result);
            } else {
                generateImageCaptcha(captchaId, result);
            }
            
            return result;
        } catch (Exception e) {
            log.error("生成验证码失败", e);
            throw new RuntimeException("生成验证码失败");
        }
    }
    
    /**
     * 生成图片验证码
     */
    private void generateImageCaptcha(String captchaId, Map<String, String> result) {
        String captchaText = captchaProducer.createText();
        BufferedImage image = captchaProducer.createImage(captchaText);
        captchaStore.put(captchaId, captchaText);
        
        String base64Image = imageToBase64(image);
        result.put("image", "data:image/png;base64," + base64Image);
        result.put("type", "image");
    }
    
    /**
     * 生成数学计算验证码
     */
    private void generateMathCaptcha(String captchaId, Map<String, String> result) {
        int num1 = random.nextInt(10) + 1;
        int num2 = random.nextInt(10) + 1;
        int operator = random.nextInt(3); // 0:加法, 1:减法, 2:乘法
        
        String expression;
        String answer;
        
        switch (operator) {
            case 0: // 加法
                expression = num1 + " + " + num2 + " = ?";
                answer = String.valueOf(num1 + num2);
                break;
            case 1: // 减法 (确保结果为正数)
                if (num1 < num2) {
                    int temp = num1;
                    num1 = num2;
                    num2 = temp;
                }
                expression = num1 + " - " + num2 + " = ?";
                answer = String.valueOf(num1 - num2);
                break;
            case 2: // 乘法
                expression = num1 + " × " + num2 + " = ?";
                answer = String.valueOf(num1 * num2);
                break;
            default:
                expression = num1 + " + " + num2 + " = ?";
                answer = String.valueOf(num1 + num2);
        }
        
        captchaStore.put(captchaId, answer);
        result.put("expression", expression);
        result.put("type", "math");
    }
    
    public boolean validateCaptcha(String captchaId, String userInput) {
        String correctCaptcha = captchaStore.remove(captchaId);
        if (correctCaptcha == null) {
            return false;
        }
        return correctCaptcha.equalsIgnoreCase(userInput);
    }
    
    private void cleanExpiredCaptcha() {
        // 实际项目中应该记录验证码的创建时间，并清理超时的验证码
        captchaStore.clear();
    }
    
    private String imageToBase64(BufferedImage image) {
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            ImageIO.write(image, "png", baos);
            return Base64.getEncoder().encodeToString(baos.toByteArray());
        } catch (Exception e) {
            log.error("验证码图片转换失败", e);
            throw new RuntimeException("验证码图片生成失败");
        }
    }
} 